package oop;

import java.awt.Color;
import java.awt.Graphics;

/**
 *
 * Lớp Entity cho Player và Bot
 */
public abstract class Entity {

    // Các hướng di chuyển
    public static final int DIRECTION_UP = 0;
    public static final int DIRECTION_RIGHT = 1;
    public static final int DIRECTION_DOWN = 2;
    public static final int DIRECTION_LEFT = 3;

    // Màu máu
    private final Color colorBackground = new Color(0xC0C0C0);
    private final Color colorStrong = new Color(0x14CE00);
    private final Color colorMedium = new Color(0xEAEA00);
    private final Color colorWeak = new Color(0xD20000);

    // Thuộc tính
    protected int x, y;
    protected volatile int direction = DIRECTION_UP;  // Hướng hiện tại
    protected double health;
    protected double attack;
    protected double defense;
    protected double range;
    protected double damage;

    protected boolean active = true;        // Còn sống hay không?
    volatile boolean updateDirection = false; // Có thay đổi hướng?
    volatile boolean updatePosition = true;   // Hay là thay đổi vị trí? 

    public final Sprite sprite;                  // Hiện thị các frame
    protected Effect effect;                      // Hiện thị hiệu ứng: mất máu, chưởng
    protected Entity other;

    Entity(int x, int y, String path) {
        this.x = x;
        this.y = y;
        sprite = new Sprite(path, 45, 90);      // Đang mặc định mỗi hình kích thước 40x80
    }

    /**
     * Cài đặt đối thủ
     *
     * @param other đối thủ
     */
    public void setRival(Entity other) {
        this.other = other;
    }

    /**
     * Cài đặt các thuộc tính
     *
     * @param typeAttack kiểu tấn công
     * @param health lượng máu
     * @param attack công
     * @param defense thủ
     * @param range tầm đánh
     */
    public void setProperty(int typeAttack, double health, double attack, double defense, double range) {
        effect = new Effect(this, typeAttack);
        this.health = health;
        this.attack = attack;
        this.defense = defense;
        this.range = range;
    }

    double getHealth() {
        return health;
    }

    double getAttack() {
        return attack;
    }

    double getDefense() {
        return defense;
    }

    double getRange() {
        return range;
    }

    /**
     * Cập nhật di chuyển
     */
    public void refresh() {
        if (updatePosition) {    // Không có sự chuyển hướng
            sprite.nextFrameE();  // => chuyển frame bên cạnh trong hướng đang đi
            move();
        }
        if (updateDirection) { // Có sự chuyển hướng

            updateDirection = false;
            updatePosition = true;
            sprite.setFrameE(direction, false); // Set mảng frame mới cho hướng mới
        }
    }

    /**
     * Hàm để vẽ tất cả lên Screen
     *
     * @param g: Truyền từ Game vào
     */
    public void paint(Graphics g) {
        if (!isActive()) {
            // Đã chết => vẽ chết
            sprite.setDeadE();
        } else {
            // Vẽ thanh máu tùy theo mức độ
            g.setColor(colorBackground);
            g.fillRect(this.x - 3, this.y - 10, 50, 3);

            if (health > 490) {
                g.setColor(colorStrong);
            }

            if (200 < health && health <= 490) {
                g.setColor(colorMedium);
            }

            if (health <= 200) {
                g.setColor(colorWeak);
            }
            g.fillRect(x - 3, y - 10, (int) this.health * 50 / 1000, 3);

        }
        // Vẽ nhân vật
        sprite.paint(g, x, y);  // vẽ frame lên, xem cài đặt Sprite

        // Vẽ hiệu ứng attack, mất máu nếu có
        effect.paint(g);

    }

    /**
     * Hàm di chuyển, di chuyển 1 bước 5px
     */
    public void move() {
        switch (direction) {
            case DIRECTION_UP:
                y -= 5;
                break;
            case DIRECTION_LEFT:
                x -= 5;
                break;
            case DIRECTION_RIGHT:
                x += 5;
                break;
            case DIRECTION_DOWN:
                y += 5;
                break;
        }
    }

    /**
     * Hàm tấn công: gọi hiệu ứng, tính sát thương
     *
     * @param other : đối thủ
     */
    public void attack(Entity other) {
        sprite.setFrameE(direction, true);
        effect.attack(other);
        // hướng đánh cho phép
//        switch (direction) {
//            case DIRECTION_UP:
//                if (y > other.y) {
//                    ;
//                }calDamage(other);
//                }
//                break;
//            case DIRECTION_DOWN:
//                if (y < other.y) {
//                    calDamage(other);
//                }
//                break;
//            case DIRECTION_RIGHT:
//                if (x < other.x) {
//                    calDamage(other);
//                }
//                break;
//            case DIRECTION_LEFT:
//                if (x > other.x) {
//                    calDamage(other);
//                }
//                break;
//
//        }
    }

    /**
     * Hàm kiểm thay đổi hướng di chuyển
     *
     * @param newDirection : Hướng mới
     */
    protected void changeDirection(int newDirection) {
        boolean changed = direction != newDirection;
        direction = newDirection;
        if (changed) {          // Có sự thay đổi về hướng đi ??
//            System.out.println("Change direction");
            updateDirection = true;
            updatePosition = false;
        }
    }

    /**
     * Hàm tính sát thương cho mình bị tấn công
     */
    public void toHit() {
        if (!isActive()) {
            return;
        }
        health -= 12;
        damage = 12;
        effect.pushDamage();

    }

    /**
     * Hàm tính sát thương cho địch
     * @deprecated  đã bỏ, do không phù hợp với vũ khí
     * @param other 
     */
    private void calDamages(Entity other) {
        /* Đối với player
         * bot.máu = (player.công - bot.thủ)* (- k*k + tamDanh*k)*(4/tamDanh^2)
         * k là khoảng cách giữa hai Entity
         */
        if (!other.isActive()) {
            return;
        }
        double intervale = Math.sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y));
//        System.out.println("Khoang canh: " + intervale);
        if (intervale <= range) {
            other.damage = (this.attack - other.defense)
                    * (-intervale * intervale + this.range * intervale)
                    * (4 / (this.range * this.range));
            other.health -= other.damage;
            // Gọi hàm mất máu cho đối phương
            other.effect.pushDamage();

        }

    }

    /**
     * Nhân vật còn sống hay không?
     *
     * @return sống or chết
     */
    public boolean isActive() {
        return health > 0;
    }

}
